• Handling Default and Cancel Buttons and Other Notifications
• Moveable and Non-moveable Dialogs
• Centering Dialogs on the Screen
• Dialogs with Text-edit Views
• Things that are Allowed in Modal Dialogs
• Things You Should Not Do in Modal Dialogs
• Modeless Dialogs
• Native Platform Alert Boxes
Abstract
This Engineering note explains how to use the class FW_CDialogFrame to implement dialog boxes with minimal work. See also the document "About Box" in Engineering Notes:Miscellaneous: which describes the subclass FW_CAboutFrame for adding a standard About box to your part.
Modal Dialogs
Basic Steps
The basic steps to add a modal dialog to your part are:
1) Create a subclass of FW_CDialogFrame
2) Register a presentation for the dialog and create the dialog frame in YourPart::NewFrame.
3) Create the dialog views in your resource file, or in your code with the CreateSubViews method.
4) Add initialization code if necessary.
5) Add code to handle messages in your dialog's HandleNotification method.
The framework does the ground work for you:
• It creates a new window with the style of your choice when you call NewModalDialog.
• It creates a new instance of your DialogFrame class when opening the new window.
• It sets OpenDoc's modal focus and disables the menu bar.
• It handles keyboard binding for default and cancel buttons
• It handles text-edit views.
Following is the code to open the Password dialog of the Form example.
// ----- Create new dialog window with the "Password" presentation -----
CPwdDialogFrame* dialog = (CPwdDialogFrame*)
FW_CDialogFrame::NewModalDialog(ev,
GetPart(ev), // Your part
dialogPresentation, // Used in CFormPart::NewFrame
size, // Window size
position, // Window position
FW_kHasCaption, // Style to make dialog moveable
FW_CString("Password")); // Title for moveable dialog
if (dialog != NULL)
{
dialog->Initialize(ev, this);
dialog->GetWindow(ev)->Show(ev);
}
}
Unlike the standard Mac Toolbox "ModalDialog" FW_CDialogFrame::NewModalDialog returns right after creating the dialog. Events are processed the same way as any other OpenDoc frames, except that the modal focus is set. NewModalDialog can return NULL if the dialog creation failed because the modal focus could not be granted.
After calling NewModalDialog you get a chance to initialize the dialog before opening the window yourself. In this example Initialize is a private method of CPwdDialogFrame which simply sets a pointer back to the calling frame. If you don't require any initialization code you can call NewAndShowModalDialog which does the Show for you.
The dialog frame itself must be created by your part's NewFrame method like other frames, a dialog is another kind of presentation for the part.
FW_CFrame* CFormPart::NewFrame(...)
{
...
else if (presentation == fPwdDialogPresentation) {
Note: In this example we pass the resource id kPasswordDialog to load the views from resource. If you leave the id null you need to implement a CreateSubViews method in your dialog class.
While the modal dialog is visible the menu bar is disabled, except for the Edit menu if a text-edit view is active.
Handling Default and Cancel Buttons and Other Notifications
Usually your dialog will have a default button, "OK" or "Yes", and a cancel button, "Cancel" or "No". The default button is drawn with a thick border to show that it responds to the <RETURN> or <ENTER> keys. The cancel button responds to the <ESC> key or the standard Macintosh cancel command: <COMMAND> + <Period>. Default and cancel buttons are created like other push buttons, in code or resources, and by setting their control message field to FW_kDefaultButtonMsg and FW_kCancelButtonMsg.
A FW_CDialogFrame object is also an instance of FW_MReceiver, so it can respond to notifications sent by its buttons or other notifiers. FW_CDialogFrame responds to the default and cancel buttons by closing the dialog. To add custom behavior or to respond to other controls , you must implement the HandleNotification method:
The base class method FW_CDialogFrame::HandleNotification responds only to the default and cancel messages to dismiss the dialog. If you wish to close it in response to another button (for instance a "No" button in a Yes/No/Cancel dialog) you can define a custom message for that button and do the following:
if (notification.GetMessage() == kMyCloseMsg)
{
// Close the dialog. Do not do anything after this, the dialog is gone!
GetWindow(ev)->CloseAndRemove(ev);
return;
}
To make a button notify the dialog, you need to call FW_CControl:LinkControlTo in code or define the control receiver field in resource. See the document "Using Controls" for more information.
Moveable and Non-moveable Dialogs
The difference between creating a moveable and non-moveable modal dialog is only the window style. Use the window style FW_kHasCaption to make the dialog moveable and pass a string for the window title. Leave the window style as 0 to make the dialog non-moveable and pass an empty string FW_CString() for the title. In general it's better to keep the dialog box moveable as this allows the user to switch to other processes.
Centering Dialogs on the Screen
ODF will center the dialog box automatically if you pass a window style containing FW_kStandardDialogPosition. In the sample code above use the following style argument:
FW_CDialogFrame adds a view tabber and an idler by default to handle text-edit views. You don't need to remember to add them like you would in a FW_CFrame object.
Things that are Allowed in Modal Dialogs
• You are allowed to open another modal dialog above the current one. ODF lets your dialog frame relinquish the modal focus as long as the new frame who wants it belongs to the same part.
• You are allowed to open a native platform alert box.
• You are allowed to support Undo/Redo in an edit view (you can use the CScrollEditView class of the Form example). In this case it is recommended to clear the undo/redo action history when you delete the modal dialog. See the comments in the constructor and destructor of CPwdDialogFrame in Form.
Things You Should Not Do in Modal Dialogs
• You should not try to execute any code after calling the base class FW_CDialogFrame::HandleNotification which will close and delete the dialog in response to the default and cancel buttons.
• You should not try to open a non-modal window .
• You should not try to embed other parts in your dialog frame.
Modeless Dialogs
Modeless dialog boxes are more like regular windows than modal dialog boxes. They can be activated and deactivated, and they don't need to be dismissed for your part to become active and editable.
ODF 1 doesn't provide any special support for modeless dialogs. In the future we plan to provide a way of sharing modeless dialogs between similar parts the same way floating windows can be shared now.
Native Platform Alert Boxes
For simple alert boxes you don't need to use the FW_CDialogFrame class, you can open native alert windows directly with the API declared in FWAlert.h: FW_Alert, FW_NoteAlert, FW_QuestionAlert, FW_ErrorAlert. These functions are documented in the Toolbox subsystem of the ODF Class Reference.
Alert boxes are system modal windows. If a notification triggers an alert box, nothing else can be executed until the alert is closed, which can lead to problems if other notifications are waiting to be processed. The work-around is to use a FW_CModalDialog instead.